package com.nhc.database.manager;

import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.graphics.Point;
import android.media.MediaPlayer;
import android.widget.Toast;

import com.astrob.activitys.AppContext;
import com.astrob.model.LonLat;
import com.astrob.naviframe.Start;
import com.astrob.nhcmap.R;
import com.astrob.util.StringUtils;
import com.astrob.util.SysUtils;
import com.astrob.util.Utils;
import com.iflytek.tts.TtsService.TtsSpeaker;
import com.nhc.database.dbmodel.Route;
import com.nhc.database.dbmodel.SystemAllInfo;
import com.nhc.database.dbmodel.TrackPoint;
import com.nhc.database.dbmodel.WayPoint;
import com.nhc.database.dbmodel.WayTrail;
import com.nhc.database.greendao.RouteDao;
import com.nhc.database.greendao.TrackPointDao;
import com.nhc.database.greendao.WayPointDao;
import com.nhc.database.greendao.WayTrailDao;
import com.nhc.model.TripDatainfo;

import org.greenrobot.greendao.database.Database;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;


/**
 * Created by colin on 2017/6/9.
 */

//航点查询后保存到内存，避免显示时一直查询数据库
public class DBDataCenter {

    private static DBDataCenter instance = new DBDataCenter();

    public static DBDataCenter getInstance() {
        return instance;
    }

    public void init() {
        doQueryWayPoint();
        doQueryRoute();
        doQueryWayTrail();
        doQueryWarning();

        //当前航迹
        long id = SysUtils.getInstance().getWaytrailID();
        wayTrailThis = getWayTrailByID(id);

        //启动后需删除3天之前的行程（非航迹的点）--需当前时间确定后
//        clearTrippt();
    }

    public WayPoint makerEdit = null;//WayPoint没有Serializable不能直接传入activity, 此为编辑的航点
    public WayPoint makerNavi = null;//导航的航点
    public WayPoint makerSeach = null;//查询的结果

    public Route routeEdit = null;//编辑的航线
    public Route routeShow = null;//地图上显示的航线（主地图上不使用）
    public Route routeNavi = null;//地图上导航的航线（主地图上使用）
    public int routeNaviIndex = 0;//航线导航的目的地index


    public WayTrail wayTrailThis = null;//当前航迹
    public TrackPoint lastTrackPoint = null;//当前航迹的上一个TrackPoint

    public WayTrail wayTrailEdit = null;//编辑的航迹
    public WayTrail wayTrailNavi = null;//导航的航迹

    //航点列表
    private ArrayList<WayPoint> waypointList = new ArrayList<WayPoint>();

    //航线列表
    private ArrayList<Route> routeList = new ArrayList<Route>();

    //航迹列表
    private ArrayList<WayTrail> waytrailList = new ArrayList<WayTrail>();

    //警告点列表
    private ArrayList<WayPoint> warningList = new ArrayList<WayPoint>();

    //航点
    //数据库查询， 1.初始化查询一次 2.save完成后查询一次
    public void doQueryWayPoint() {
        waypointList.clear();
        WayPointDao wayPointDao = AppContext.getInstances().getDaoSession().getWayPointDao();
        try {
            //只显示routeid为0的航点，航线上的航点不能直接删除
            waypointList = (ArrayList) wayPointDao.queryBuilder()
                    .where(WayPointDao.Properties.Routeid.eq(0))
                    .orderAsc(WayPointDao.Properties.Id)
                    .build().list();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void doDeleteAllPoint() {
        if (waypointList == null || waypointList.size() < 1) {
            return;
        }

        ArrayList<Long> pkIds = new ArrayList<Long>();
        for (WayPoint wp : waypointList) {
            pkIds.add(wp.getId());
        }
        doDeleteWayPoint(pkIds);
    }

    public void doDeleteWayPoint(ArrayList<Long> pkIds) {
        if (pkIds != null && pkIds.size() > 0) {
            WayPointDao wayPointDao = AppContext.getInstances().getDaoSession().getWayPointDao();
            wayPointDao.deleteByKeyInTx(pkIds);
            doQueryWayPoint();
        }

        if (waypointList.size() < 1) {
            //清空航点后，缺省名重置
            SystemAllInfo sInfo = SystemCenter.getInstance().getSysInfo("WayPointIndex");
            if (sInfo == null) {
                sInfo = new SystemAllInfo(null, "WayPointIndex", "0");
            } else {
                sInfo.setContent("0");
            }
            SystemCenter.getInstance().saveSysInfo(sInfo);
        }
    }

    //航线
    public void doQueryRoute() {
        RouteDao routeDao = AppContext.getInstances().getDaoSession().getRouteDao();
        try {
            routeList = (ArrayList) routeDao.queryBuilder()
                    .where(RouteDao.Properties.Id.notEq(0))
                    .orderAsc(RouteDao.Properties.Id)
                    .build().list();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void doDeleteAllRoute() {
        if (routeList == null || routeList.size() < 1) {
            return;
        }

        ArrayList<Long> pkIds = new ArrayList<Long>();
        for (Route route : routeList) {
            pkIds.add(route.getId());
        }

        RouteDao routeDao = AppContext.getInstances().getDaoSession().getRouteDao();
//        routeDao.deleteAll(); //还需删除航线上的航点
        doDeleteRoute(pkIds);
    }

    public void doDeleteRoute(ArrayList<Long> pkIds) {
        if (pkIds != null && pkIds.size() > 0) {
            RouteDao routeDao = AppContext.getInstances().getDaoSession().getRouteDao();
            routeDao.deleteByKeyInTx(pkIds);

            //删除航线上的航点  ---执行SQL---
            String strRouteIds = "";
            for (int i = 0; i < pkIds.size(); i++) {
                if (i == 0) {
                    strRouteIds += pkIds.get(i) + "";
                } else {
                    strRouteIds += "," + pkIds.get(i);
                }
            }
            if (strRouteIds.length() > 0) {
                WayPointDao wayPointDao = AppContext.getInstances().getDaoSession().getWayPointDao();
                try {
                    String deletesql = "DELETE FROM WAY_POINT WHERE ROUTEID IN (" + strRouteIds + ");";
//                    String deletesql = "DELETE FROM WAY_POINT WHERE ROUTEID <> 0";
                    wayPointDao.getDatabase().execSQL(deletesql);
                } catch (SQLException e) {
                    return;
                }
            }

            //重新查询航线
            doQueryRoute();
        }
    }

    //航迹
    public void doQueryWayTrail() {
        WayTrailDao wayTrailDao = AppContext.getInstances().getDaoSession().getWayTrailDao();
        try {
            waytrailList = (ArrayList) wayTrailDao.queryBuilder()
                    .where(WayTrailDao.Properties.Id.notEq(0))
                    .orderAsc(WayTrailDao.Properties.Id)
                    .build().list();
        } catch (Exception e) {
            e.printStackTrace();
        }

        //查询数据库时，当前航迹的状态因还没有保存，会和实际的不一致
        if (wayTrailThis != null) {
            for (WayTrail wt : waytrailList) {
                if (wayTrailThis.getId() == wt.getId()) {
                    wt = wayTrailThis;
                    break;
                }
            }
        }
    }

    public WayTrail getWayTrailByID(long id) {

        if (id == 0L) {
            return null;
        }
        ArrayList<WayTrail> waytrailListA = new ArrayList<WayTrail>();

        WayTrailDao wayTrailDao = AppContext.getInstances().getDaoSession().getWayTrailDao();
        try {
            waytrailListA = (ArrayList) wayTrailDao.queryBuilder()
                    .where(WayTrailDao.Properties.Id.eq(id))
                    .orderAsc(WayTrailDao.Properties.Id)
                    .limit(1)
                    .build().list();
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (waytrailListA.size() > 0) {
            return waytrailListA.get(0);
        }

        return null;
    }

    //开启新的航迹
    public boolean startThisWayTrail() {
        if (wayTrailThis != null) {
            saveWayTrail(wayTrailThis, true);//如果有则先保存一次
        }
        wayTrailThis = new WayTrail("");
        wayTrailThis.setColorstyle(1);
        wayTrailThis.setIsshow(true);
        Long id = saveWayTrail(wayTrailThis, true);
        wayTrailThis.setId(id);
        if (id > 0L) {
            return true;
        }
        return false;
    }

    public boolean pauseThisWayTrail(boolean isPause) {
        if (wayTrailThis == null) {
            return false;
        }
        wayTrailThis.setIsPause(isPause);
        return true;
    }

    public boolean closeThisWayTrail() {
        if (wayTrailThis == null) {
            return false;
        }
        wayTrailThis.setIsPause(true);
        //计算填充当前的航迹信息
        wayTrailThis = reUpdateWayTrail(wayTrailThis);
        wayTrailThis.setIsshow(true);//保存后显示
        Long id = saveWayTrail(wayTrailThis, false);
        wayTrailThis = null;
        if (id > 0L) {
            return true;
        }
        return false;
    }

    //当前航迹另存为
    public boolean saveAsThisWayTrail() {
        if (wayTrailThis == null) {
            return false;
        }
        WayTrail wt = new WayTrail();
        wt.clone(wayTrailThis);
        if (wt.trackPointList.size() < 1) {
            return false;
        }
        wt.setIsPause(true);
        //计算填充当前的航迹信息
        wt = reUpdateWayTrail(wt);
        wt.setIsshow(false);

        WayTrailDao wayTrailDao = AppContext.getInstances().getDaoSession().getWayTrailDao();
        long id = wayTrailDao.insert(wt);

        for (int i = 0; i < wt.trackPointList.size(); i++) {
            wt.trackPointList.get(i).setWaytrail_id(id);
        }
        saveTrackPointList(wt.trackPointList);

        doQueryWayTrail();

        return true;
    }

    public WayTrail reUpdateWayTrail(WayTrail wt) {
        if (wt == null) {
            return null;
        }

        boolean isLocalWt = true;
        if (wt.getStarttime() == 0) {
            //非本机记录的轨迹，来自于gpx和KML，无日期时间??
            isLocalWt = false;
        }

        ArrayList<TrackPoint> tpList = getTrackPointByWayTrail(wt, null);
        int num = tpList.size();
        if (num < 2) {
            return wt;
        }
        //保存的航迹点时间肯定都是正确的
        wt.setNum(num);

        TrackPoint tpA = tpList.get(0);
        TrackPoint tpB = tpList.get(num - 1);
        double line_distance = Start.getInstance().MapKit().getDistance(tpA.getLL(), tpB.getLL());
        wt.setTrail_distance(line_distance);
        wt.setEndtime(tpB.getDatetime());
        wt.setTotaltime((int) ((tpB.getDatetime() - tpA.getDatetime())) / 1000);//秒

        if (wt.getTotaltime() < 1) {
            wt.setTotaltime(num);//如果没有时间则1个点1秒
        }

        //统计航段时间，航段速度
        int movingtime = 0;

        //----计算时是否要考虑精度
        double minH = 10000000;//最小海拔高度
        double maxH = -10000000;//最大海拔高度
        double avgH = 0; //平均海拔高度
        double up = 0;
        double down = 0;
        double trail_distance = 0;//包括乘车距离
        boolean needsave = false;
        ArrayList<LonLat> points = new ArrayList<LonLat>();
        for (int i = 0; i < num; i++) {
            if (i > 0) {
                tpA = tpList.get(i - 1);
                tpB = tpList.get(i);
                double distance = Start.getInstance().MapKit().getDistance(tpA.getLL(), tpB.getLL());
                trail_distance += distance;

                //航段时间
                int t = (int) ((tpB.getDatetime() - tpA.getDatetime()) / 1000);
                if (t < 1) {
                    t = 1;
                }

                //航段速度 >= 1 km/h 则为运动
                double vel = distance / t;
                if (vel * 3.6 >= 1) {
                    movingtime += t;

                    if (tpB.getSpeed() == 0) {
                        tpB.setSpeed(vel);
                        needsave = true;
                    }
                }
            }
            double h = tpList.get(i).getAltitude();
            avgH += h;
            if (h < minH) {
                minH = h;
            }
            if (h > maxH) {
                maxH = h;
            }
            points.add(tpList.get(i).getLL());

        }

        double[] updown = Utils.getUpDown(tpList);
        if (updown != null && updown.length == 2) {
            up = updown[0];
            down = updown[1];
        }

        wt.trackPointList = tpList;
        if (needsave) {
            saveTrackPointList(wt.trackPointList);
        }

        wt.setUp(up);
        wt.setDown(down);
        wt.setTrail_distance(trail_distance);
        wt.setMinalt((int) minH);
        wt.setMaxalt((int) maxH);
        avgH /= num;
        wt.setArea((int) Utils.calculateArea(points));

        wt.setMovingtime(movingtime);
        wt.setStoptime(wt.getTotaltime() - movingtime);//无记录的点也是停止时间。
        wt.setMovingdistance((int) trail_distance);
        if (movingtime > 0) {
            float averagevel = (float)(trail_distance/movingtime);
            wt.setAveragevel(averagevel);
        }

        return wt;
    }

    public Long getThisWayTrailID() {
        if (wayTrailThis == null) {
            return 0L;
        }
        return wayTrailThis.getId();
    }

    //快速的保存，是否显示
    public Long saveWt(WayTrail wt) {
        if (wt == null) {
            return 0L;
        }
        WayTrailDao wayTrailDao = AppContext.getInstances().getDaoSession().getWayTrailDao();
        return wayTrailDao.insertOrReplace(wt);
    }

    public Long saveWayTrail(WayTrail wayTrail, boolean isEdit) {
        if (wayTrail == null) {
            return 0L;
        }
        if (wayTrail.getName().length() < 1) {
            String name = SysUtils.getInstance().getTimeStr(System.currentTimeMillis());
            wayTrail.setName(name);
        }
        WayTrailDao wayTrailDao = AppContext.getInstances().getDaoSession().getWayTrailDao();

        long id = 0;
        if (wayTrail.getId() == null) {
            id = wayTrailDao.insert(wayTrail);
            SysUtils.getInstance().saveWaytrailID(id);
        } else {
            //手动保存
            wayTrailDao.update(wayTrail);

            //必需保存，否则出现bug：点击记录轨迹后 地图上没画出轨迹的时候 变更当前轨迹颜色，然后地图上不显示当前轨迹，但当前轨迹的所有信息均是正常的；可以理解为当前轨迹颜色是透明或没显示， 可以复现
            if (!isEdit) {
                id = wayTrail.getId();
                SysUtils.getInstance().saveWaytrailID(0L);
                ArrayList<TrackPoint> tList = getTrackPointByWayTrail(wayTrail, null);
                if (tList.size() < 5) {
                    //轨迹点低于5的轨迹不保存
                    ArrayList<Long> pkIds = new ArrayList<Long>();
                    pkIds.add(id);
                    doDeleteWayTrail(pkIds);
                    return 0L;
                }
            }
        }

        doQueryWayTrail();

        return id;
    }

    public void doDeleteAllWayTrail() {
        WayTrailDao wayTrailDao = AppContext.getInstances().getDaoSession().getWayTrailDao();
//        wayTrailDao.deleteAll();
//        doQueryWayTrail();

        //只删除航迹的点，不删除行程的点（WAYTRAIL_ID == 0）--删除改为更改
        ArrayList<Long> pkIds = new ArrayList<Long>();
        for (WayTrail wayTrail : waytrailList) {
            if (DBDataCenter.getInstance().wayTrailThis != null
                    && wayTrail.getId() == DBDataCenter.getInstance().wayTrailThis.getId()) {
                //当前航迹不清空
            } else {
                pkIds.add(wayTrail.getId());
            }
        }
        doDeleteWayTrail(pkIds);
    }

    public void doDeleteWayTrail(ArrayList<Long> pkIds) {
        if (pkIds != null && pkIds.size() > 0) {
            WayTrailDao wayTrailDao = AppContext.getInstances().getDaoSession().getWayTrailDao();
            wayTrailDao.deleteByKeyInTx(pkIds);

            String strWayTrailIds = "";
            for (int i = 0; i < pkIds.size(); i++) {
                if (i == 0) {
                    strWayTrailIds += pkIds.get(i) + "";
                } else {
                    strWayTrailIds += "," + pkIds.get(i);
                }
            }

            if (strWayTrailIds.length() > 0) {
                TrackPointDao trackPointDao = AppContext.getInstances().getDaoSession().getTrackPointDao();
                try {
                    //修改航迹的点--不删除只是修改
                    String strSQL = "UPDATE TRACK_POINT SET WAYTRAIL_ID = 0 WHERE WAYTRAIL_ID IN (" + strWayTrailIds + ");";
                    //删除航迹上的点  ---执行SQL---
//                    strSQL = "DELETE FROM TRACK_POINT WHERE WAYTRAIL_ID IN (" + strWayTrailIds + ");";
                    trackPointDao.getDatabase().execSQL(strSQL);
                } catch (SQLException e) {
                    return;
                }

                //test
//                ArrayList<TrackPoint> trackPointList = (ArrayList) trackPointDao.queryBuilder()
//                        .where(TrackPointDao.Properties.Waytrail_id.eq(pkIds.get(0)))
//                        .orderAsc(TrackPointDao.Properties.Id)
//                        .build().list();
//
//                int c = trackPointList.size();
//                c++;
            }


            doQueryWayTrail();
        }
    }

    //清空航迹点
    public void doDeleteWayTrailTP(Long WayTrailId) {
        TrackPointDao trackPointDao = AppContext.getInstances().getDaoSession().getTrackPointDao();
        try {
            //修改航迹的点--不删除只是修改
            String strSQL = "UPDATE TRACK_POINT SET WAYTRAIL_ID = 0 WHERE WAYTRAIL_ID = " + WayTrailId + ";";
            trackPointDao.getDatabase().execSQL(strSQL);
        } catch (SQLException e) {
            return;
        }
    }

    //航迹排序
    //"按创建日期排序", "按名称排序", "按距离排序"，"按航点数量排序"
    public final static Comparator<WayTrail> waytrailFunc0 = new Comparator<WayTrail>() {
        @Override
        public int compare(WayTrail object1, WayTrail object2) {
//            return (int) (object1.getId() - object2.getId());
            return (int) (object1.getStarttime() - object2.getStarttime());
        }
    };

    public final static Comparator<WayTrail> waytrailFunc1 = new Comparator<WayTrail>() {
        @Override
        public int compare(WayTrail object1, WayTrail object2) {
            return object1.getName().compareToIgnoreCase(object2.getName());
        }
    };

    public final static Comparator<WayTrail> waytrailFunc2 = new Comparator<WayTrail>() {
        @Override
        public int compare(WayTrail object1, WayTrail object2) {
            return (int) (object1.getTrail_distance() - object2.getTrail_distance());
        }
    };

    public final static Comparator<WayTrail> waytrailFunc3 = new Comparator<WayTrail>() {
        @Override
        public int compare(WayTrail object1, WayTrail object2) {
            return (int) (object1.getNum() - object2.getNum());
        }
    };

    public ArrayList<WayTrail> searchWayTrail(String keyword) {
        ArrayList<WayTrail> waytrailListA = new ArrayList<WayTrail>();

        if (keyword != null && keyword.length() > 0) {
            for (WayTrail wt : waytrailList) {
                if (wt.getName().contains(keyword)) {
                    waytrailListA.add(wt);
                }
            }
        } else {
            waytrailListA = waytrailList;
        }

        return waytrailListA;
    }

    //TrackPoint 航迹点
    public boolean saveTrackPoint(TrackPoint trackPoint) {
        if (trackPoint == null) {
            return false;
        }

        TrackPointDao trackPointDao = AppContext.getInstances().getDaoSession().getTrackPointDao();
        trackPointDao.insertOrReplace(trackPoint);
        return true;
    }

    public boolean saveTrackPointList(ArrayList<TrackPoint> trackPointlist) {
        if (trackPointlist == null || trackPointlist.size() < 1) {
            return false;
        }

        TrackPointDao trackPointDao = AppContext.getInstances().getDaoSession().getTrackPointDao();
        trackPointDao.insertOrReplaceInTx(trackPointlist);
        return true;
    }

    //启动清空行程点（无航迹id的点）
    public void clearTrippt() {
        long thisTime = System.currentTimeMillis() - 3600 * 24 * 1000 * 3;
        if (thisTime == 0 || thisTime < 1497921620000L) {
            return;
        }

        TrackPointDao trackPointDao = AppContext.getInstances().getDaoSession().getTrackPointDao();
        try {
            String deletesql = "DELETE FROM TRACK_POINT WHERE WAYTRAIL_ID = 0 AND DATETIME < " + thisTime;
            trackPointDao.getDatabase().execSQL(deletesql);
        } catch (SQLException e) {
            return;
        }
    }

    public ArrayList<TrackPoint> getThisTrackPoint(double[] regions) {
        return getTrackPointByWayTrail(wayTrailThis, regions);
    }

    public ArrayList<TrackPoint> getTrackPointByWayTrail(WayTrail wayTrail, double[] regions) {
        ArrayList<TrackPoint> trackPointList = new ArrayList<TrackPoint>();

        if (wayTrail == null) {
            return trackPointList;
        }

        TrackPointDao trackPointDao = AppContext.getInstances().getDaoSession().getTrackPointDao();

        try {
            //double[] regions = {_maxLon, _maxLat, _minLon, _minLat};
            if (regions != null && regions.length == 4) {
                //连线的原因，故需外扩
                //计算外扩的step
                trackPointList = (ArrayList) trackPointDao.queryBuilder()
                        .where(TrackPointDao.Properties.Waytrail_id.eq(wayTrail.getId()))
                        .orderAsc(TrackPointDao.Properties.Id)
                        .limit(2)
                        .build().list();

                double step = 0.01;//约1km
                //按时间间隔算
                int interval = 0;
                if (trackPointList.size() == 2) {
                    interval = (int) (trackPointList.get(1).getDatetime() - trackPointList.get(0).getDatetime());
                    interval /= 1000; //间隔xx秒, 每秒20米 约72km／h 即每秒0.0002经纬度
                    double stepA = 0.0002 * interval;//间隔5分钟=300秒 约0.06经纬度
                    if (stepA > step) {
                        step = stepA;
                    }
                }
                trackPointList.clear();

                double maxLon = regions[0] + step;
                double maxLat = regions[1] + step;
                double minLon = regions[2] - step;
                double minLat = regions[3] - step;
                trackPointList = (ArrayList) trackPointDao.queryBuilder()
                        .where(TrackPointDao.Properties.Waytrail_id.eq(wayTrail.getId()),
                                TrackPointDao.Properties.Datetime.ge(wayTrail.getStarttime()),
                                TrackPointDao.Properties.Longitude.le(maxLon),
                                TrackPointDao.Properties.Latitude.le(maxLat),
                                TrackPointDao.Properties.Longitude.ge(minLon),
                                TrackPointDao.Properties.Latitude.ge(minLat))
                        .orderAsc(TrackPointDao.Properties.Id)
                        .build().list();
            } else {
                //1. TrackPoint Waytrail_id == wayTrail id
                trackPointList = (ArrayList) trackPointDao.queryBuilder()
                        .where(TrackPointDao.Properties.Waytrail_id.eq(wayTrail.getId()))
                        .orderAsc(TrackPointDao.Properties.Id)
                        .build().list();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return trackPointList;
    }


    //警告点
    public void doQueryWarning() {
        WayPointDao wayPointDao = AppContext.getInstances().getDaoSession().getWayPointDao();
        try {
            warningList = (ArrayList) wayPointDao.queryBuilder()
                    .where(WayPointDao.Properties.Type.eq(1))
                    .orderAsc(WayPointDao.Properties.Id)
                    .build().list();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public void doDeleteAllWarning() {
        WayPointDao wayPointDao = AppContext.getInstances().getDaoSession().getWayPointDao();
        ArrayList<Long> pkIds = new ArrayList<Long>();
        for (WayPoint wp : warningList) {
            wp.setType(0);
        }
        wayPointDao.insertOrReplaceInTx(warningList);
        doQueryWarning();
        doQueryWayPoint();
    }

    public void doDeleteWarning(ArrayList<Long> pkIds) {
        if (pkIds != null && pkIds.size() > 0) {
            WayPointDao wayPointDao = AppContext.getInstances().getDaoSession().getWayPointDao();

            for (WayPoint wp : warningList) {
                if (pkIds.contains(wp.getId())) {
                    wp.setType(0);
                }
            }
            wayPointDao.insertOrReplaceInTx(warningList);
            doQueryWarning();
            doQueryWayPoint();
        }
    }

    public boolean setAsWarningPt(WayPoint wayPoint) {
        if (wayPoint == null) {
            return false;
        }
        wayPoint.setType(1);
        saveWayPoint(wayPoint);
        return true;
    }


    //获取航线上的航点(非正确顺序)
    public ArrayList<WayPoint> getWaypointListByRouteId(Long routeId) {
        ArrayList<WayPoint> wpList = new ArrayList<WayPoint>();
        WayPointDao wayPointDao = AppContext.getInstances().getDaoSession().getWayPointDao();
        try {
            //此方法有问题，能查询到两个一样的WayPoint，不能输出两个id不同的WayPoint
            wpList = (ArrayList) wayPointDao.queryBuilder()
                    .where(WayPointDao.Properties.Routeid.eq(routeId))
                    .orderAsc(WayPointDao.Properties.Id)
                    .build().list();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return wpList;
    }

    //获取航线上的航点(正确顺序)
    public ArrayList<WayPoint> getWaypointListByRoute(Route route) {
        ArrayList<WayPoint> wpList = new ArrayList<WayPoint>();
        if (route == null || route.getWaypoint() == null || route.getWaypoint().length() < 1) {
            return wpList;
        }

        String strWaypoints = route.getWaypoint();
        String waypoints[] = strWaypoints.split("-");
        if (waypoints == null || waypoints.length < 1) {
            return wpList;
        }

        strWaypoints = strWaypoints.replace("-", ",");
//        ArrayList<WayPoint> wpListA = getWaypointListByRouteId(route.getId());

        ArrayList<WayPoint> wpListA = new ArrayList<WayPoint>();
        WayPointDao wayPointDao = AppContext.getInstances().getDaoSession().getWayPointDao();
        try {
            //这样才能输出两个只有id不同的WayPoint
            wpListA = (ArrayList) wayPointDao.queryBuilder()
                    .where(WayPointDao.Properties.Id.in(Arrays.asList(waypoints)))
                    .orderAsc(WayPointDao.Properties.Id)
                    .build().list();
        } catch (Exception e) {
            e.printStackTrace();
        }
        for (int i = 0; i < waypoints.length; i++) {
            long wpId = Long.parseLong(waypoints[i]);
            for (WayPoint wp : wpListA) {
                if (wp.getId() == wpId) {
                    wpList.add(wp);
                    break;
                }
            }
        }

        return wpList;
    }

    //删除航线上的航点
    public boolean delWaypointOnRoute(Route route, ArrayList<Long> pkIds) {
        /*if (route == null || route.getWaypoint() == null || route.getWaypoint().length() < 1) {
            return false;
        }
        String waypoints[] = route.getWaypoint().split("-");
        if (waypoints == null || waypoints.length < 1) {
            return false;
        }
        if (pkIds == null || pkIds.size() < 1) {
            return false;
        }

        String waypointsNew = "";
        int j = 0;
        for (int i = 0; i < waypoints.length; i++) {
            long wpId = Long.parseLong(waypoints[i]);
            if (pkIds.contains(wpId)) {
                continue;
            }

            if (j > 0) {
                waypointsNew += "-" + wpId;
            } else {
                waypointsNew += wpId + "";
            }
            j++;
        }

        route.setWaypoint(waypointsNew);*/

        if (route == null || route.waypointList == null || route.waypointList.size() < 1) {
            return false;
        }
        String waypointsNew = "";
        int j = 0;
        int size = route.waypointList.size();
        for (int i = 0; i < size; i++) {
            Long wpId = route.waypointList.get(i).getId();
            if (pkIds.contains(wpId)) {
                continue;
            }

            if (j > 0) {
                waypointsNew += "-" + wpId;
            } else {
                waypointsNew += wpId + "";
            }
            j++;
        }
        route.setWaypoint(waypointsNew);


        saveRoute(route);
        doDeleteWayPoint(pkIds);

        return true;
    }

    public Route getRouteById(long id) {
        if (routeList == null) {
            return null;
        }

        for (Route route : routeList) {
            if (route.getId() == id) {
                return route;
            }
        }
        return null;
    }

    public Long addNewRoute() {
        String name = "001";
//        RouteDao routeDao = AppContext.getInstances().getDaoSession().getRouteDao();
//        try {
//            Database db = routeDao.getDatabase();
//            Cursor cursor = db.rawQuery("SELECT MAX(_id) FROM ROUTE ", null);
//            while (cursor.moveToNext()) {
//                Long id = cursor.getLong(0) + 1;
//                name = new DecimalFormat("000").format(id);
//                break;
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

        SystemAllInfo sInfo = SystemCenter.getInstance().getSysInfo("RouteIndex");
        if (sInfo == null) {
            sInfo = new SystemAllInfo(null, "RouteIndex", name);
        } else {
            try {
                int index = Integer.valueOf(sInfo.getContent()) + 1;
                name = new DecimalFormat("000").format(index);
            } catch (NumberFormatException e) {

            }
        }
        sInfo.setContent(name);
        SystemCenter.getInstance().saveSysInfo(sInfo);

        return saveRoute(new Route("Route" + name));
    }

    public Long saveRoute(Route route) {
        if (route == null) {
            return 0L;
        }

        RouteDao routeDao = AppContext.getInstances().getDaoSession().getRouteDao();
        long id = routeDao.insertOrReplace(route);

        doQueryRoute();

        return id;
    }

    public WayPoint createNewWayPoint(LonLat ll) {

        if (ll == null) {
            ll = new LonLat();
        }
        String name = getNewWayPointDefaultName();
        return new WayPoint(name, ll);
    }

    public String getNewWayPointDefaultName() {
        String name = "0001";
        Collections.sort(waypointList, waypointFunc0);
        int size = waypointList.size();
        byte[] hashMap = new byte[1250];
        int tmp = 1;
        int max = 0;
        for (int i = 0; i < size; i++) {
            tmp = StringUtils.toInt(waypointList.get(i).getName());
            if (tmp > 0) {
                tmp -= 1;
            }
            hashMap[tmp / 8] |= 1 << (tmp % 8);
        }

        for (int i = 0; i < 10000; i++) {
            if (((hashMap[i / 8] >> (i % 8)) & 1) == 0) {
                max = i;
                break;
            }
        }
        return new DecimalFormat("0000").format(max + 1);
    }

    public String getNewWayPointDefaultName2() {
        String name = "0001";
//        int index = 0;
//        SystemAllInfo sInfo = SystemCenter.getInstance().getSysInfo("WayPointIndex");
//        if (sInfo == null) {
//            sInfo = new SystemAllInfo(null, "WayPointIndex", name);
//        } else {
//            try {
//                index = Integer.valueOf(sInfo.getContent()) + 1;
//                name = new DecimalFormat("000").format(index);
//            } catch (NumberFormatException e) {
//
//            }
//        }
//        sInfo.setContent(name);
//        SystemCenter.getInstance().saveSysInfo(sInfo);

        //取上一个保存航点的名称; 航点未保存则WayPointIndex不增加
        int lastindex = 0;
        Collections.sort(waypointList, waypointFunc0);
        int size = waypointList.size();
        if (size > 0) {
            for (int i = 0; i < size; i++) {
                WayPoint wp = waypointList.get(size - 1 - i);
                lastindex = StringUtils.toInt(wp.getName());
                if (lastindex > 0) {
                    String name0 = new DecimalFormat("0000").format(lastindex);
                    if (name0.compareTo(wp.getName()) == 0) {
                        name = new DecimalFormat("0000").format(lastindex + 1);
                        break;
                    }
                }
            }
        }
        return name;
    }

    public Long saveWayPoint(WayPoint wayPoint) {
        if (wayPoint == null) {
            return 0L;
        }
        WayPointDao wayPointDao = AppContext.getInstances().getDaoSession().getWayPointDao();
        long id = wayPointDao.insertOrReplace(wayPoint);

        if (wayPoint.getRouteid() == 0) {
            doQueryWayPoint();
            if (wayPoint.getType() == 1) {
                doQueryWarning();
            }
        }

        return id;
    }

    //只保留get，不能set，
    public ArrayList<WayPoint> getWaypointList() {
        return waypointList;
    }

    public ArrayList<Route> getRouteList() {
        return routeList;
    }

    public final static Comparator<Route> routeFunc0 = new Comparator<Route>() {
        @Override
        public int compare(Route object1, Route object2) {
//            return (int) (object1.getId() - object2.getId());
            return (int) (object1.getDatetime() - object2.getDatetime());
        }
    };

    public final static Comparator<Route> routeFunc1 = new Comparator<Route>() {
        @Override
        public int compare(Route object1, Route object2) {
            return object1.getName().compareToIgnoreCase(object2.getName());
        }
    };

    public ArrayList<Route> getRouteList(int order) {
        if (routeList.size() < 2) {
            return routeList;
        }

        switch (order) {
            default:
            case 0:
                Collections.sort(routeList, routeFunc0);
                break;
            case 1:
                Collections.sort(routeList, routeFunc1);
                break;
        }

        return routeList;
    }


    public ArrayList<WayTrail> getWaytrailList() {
        return waytrailList;
    }

    public ArrayList<WayPoint> getWarningList() {
        return warningList;
    }

    public ArrayList<WayTrail> getWaytrailListByOrder(int order) {
        if (waytrailList.size() < 2) {
            return waytrailList;
        }

        switch (order) {
            default:
            case 0:
                Collections.sort(waytrailList, waytrailFunc0);
                break;
            case 1:
                Collections.sort(waytrailList, waytrailFunc1);
                break;
            case 2:
                Collections.sort(waytrailList, waytrailFunc2);
                break;
            case 3:
                Collections.sort(waytrailList, waytrailFunc3);
                break;
        }

        return waytrailList;
    }

    //航点输出排序 0-id 时间  1-name 2-距离
    public ArrayList<WayPoint> getWaypointListByOrder(int order) {

        LonLat llcar = SysUtils.getInstance().getLL();
        for (WayPoint wp : waypointList) {
            double distance = (int) Start.getInstance().MapKit().getDistance(wp.getLL(), llcar);
            wp.setDistance(distance);
        }

        if (waypointList.size() < 2) {
            return waypointList;
        }
        switch (order) {
            default:
            case 0:
                Collections.sort(waypointList, waypointFunc0);
                break;
            case 1:
                Collections.sort(waypointList, waypointFunc1);
                break;
            case 2:
                Collections.sort(waypointList, waypointFunc2);
                break;
        }

        return waypointList;
    }

    //按id排序，并非是按时间
    public final static Comparator<WayPoint> waypointFunc0 = new Comparator<WayPoint>() {
        @Override
        public int compare(WayPoint object1, WayPoint object2) {
//            return (int) (object1.getId() - object2.getId());
            return (int) (object1.getDatetime() - object2.getDatetime());
        }
    };

    public final static Comparator<WayPoint> waypointFunc1 = new Comparator<WayPoint>() {
        @Override
        public int compare(WayPoint object1, WayPoint object2) {
            return object1.getName().compareToIgnoreCase(object2.getName());
        }
    };

    public final static Comparator<WayPoint> waypointFunc2 = new Comparator<WayPoint>() {
        @Override
        public int compare(WayPoint object1, WayPoint object2) {
            return (int) (object1.getDistance() - object2.getDistance());
        }
    };

    //50m范围
    //llcenter--原始坐标
    public WayPoint getNearWaypt(LonLat llcenter) {
        if (waypointList == null || waypointList.size() < 1) {
            return null;
        }

        double _maxLon, _maxLat, _minLon, _minLat;
        double range = 0.0001;
        _maxLon = llcenter.GetLon() + range;
        _maxLat = llcenter.GetLat() + range;
        _minLon = llcenter.GetLon() - range;
        _minLat = llcenter.GetLat() - range;

        ArrayList<WayPoint> waypointListB = new ArrayList<WayPoint>();
        for (WayPoint wp : waypointList) {
            if (wp.getLL().GetLon() > _maxLon || wp.getLL().GetLat() > _maxLat
                    || wp.getLL().GetLon() < _minLon || wp.getLL().GetLat() < _minLat) {
                continue;
            }
            double distance = Start.getInstance().MapKit().getDistance(wp.getLL(), llcenter);
            wp.setDistance(distance);
            waypointListB.add(wp);
        }

        if (waypointListB.size() < 1) {
            return null;
        }

        if (waypointListB.size() > 2) {
            Collections.sort(waypointListB, waypointFunc2);
        }

        return waypointListB.get(0);
    }

    public ArrayList<WayPoint> searchWaypt(String keyword, LonLat centerLL, boolean isAll) {
        ArrayList<WayPoint> waypointListA = new ArrayList<WayPoint>();
        if (centerLL == null || !centerLL.IsValid()) {
            return waypointListA;
        }

        boolean isThisCity = true;//当前城市,
        LonLat llcar = SysUtils.getInstance().getLL();
        int distance = (int) Start.getInstance().MapKit().getDistance(centerLL, llcar);
        if (distance > 1000) {
            isThisCity = false;
        }

        ArrayList<WayPoint> waypointListB = new ArrayList<WayPoint>();
        if (keyword != null && keyword.length() > 0) {
            for (WayPoint wp : waypointList) {
                if (wp.getName().contains(keyword)) {
                    waypointListB.add(wp);
                }
            }
        } else {
            for (WayPoint wp : waypointList) {
                distance = (int) Start.getInstance().MapKit().getDistance(wp.getLL(), centerLL);
                if (!isAll && distance > 50000) {
                    continue;
                }
                wp.setDistance(distance);
                waypointListB.add(wp);
            }
        }

        Collections.sort(waypointListB, waypointFunc2);
        return waypointListB;
    }

    public ArrayList<WayPoint> searchWayptByIcon(int icon_num) {
        ArrayList<WayPoint> waypointListA = new ArrayList<WayPoint>();
        for (WayPoint wp : waypointList) {
            if (wp.getIcon_num() == icon_num) {
                waypointListA.add(wp);
            }
        }

        return waypointListA;
    }

    public void doDeleteWayPointByIcon(int icon_num) {
        if (waypointList == null || waypointList.size() < 1) {
            return;
        }

        ArrayList<Long> pkIds = new ArrayList<Long>();
        for (WayPoint wp : waypointList) {
            if (wp.getIcon_num() == icon_num) {
                pkIds.add(wp.getId());
            }
        }
        doDeleteWayPoint(pkIds);
        doQueryWayPoint();
    }

    //设置完整航线的地图中心点和比例尺
    public void showFullRoute(ArrayList<WayPoint> wayPoints) {
        if (wayPoints == null) {
            return;
        }

        Start.getInstance().MapKit().setScale(100000);
        Start.getInstance().MapKit().setRotation(0);

        int size = wayPoints.size();
        if (size == 1) {
            LonLat ll = wayPoints.get(0).getLL_gcj();
            Start.getInstance().MapKit().setMapCenter(ll);
            return;
        }

        double MinLon = 10000;
        double MinLat = 10000;
        double MaxLon = -1000;
        double MaxLat = -1000;

        for (int i = 0; i < size; i++) {
            if (wayPoints.get(i).getLL().GetLon() < MinLon) {
                MinLon = wayPoints.get(i).getLL().GetLon();
            }

            if (wayPoints.get(i).getLL().GetLat() < MinLat) {
                MinLat = wayPoints.get(i).getLL().GetLat();
            }

            if (wayPoints.get(i).getLL().GetLon() > MaxLon) {
                MaxLon = wayPoints.get(i).getLL().GetLon();
            }

            if (wayPoints.get(i).getLL().GetLat() > MaxLat) {
                MaxLat = wayPoints.get(i).getLL().GetLat();
            }
        }

        LonLat pos = new LonLat((MinLon + MaxLon) / 2, (MinLat + MaxLat) / 2);
        pos = Utils.wgs84togcj02(pos.GetLon(), pos.GetLat());//Utils GPS to 火星坐标
        Start.getInstance().MapKit().setMapCenter(pos);
        LonLat posA = new LonLat(MinLon, MinLat);
        LonLat posB = new LonLat(MaxLon, MaxLat);
        double distance = Start.getInstance().MapKit().getDistance(posA, posB);

        if (distance < 500) {
            Start.getInstance().MapKit().setScale(100000);
        } else if (distance < 1000) {
            Start.getInstance().MapKit().setScale(50000);
        } else if (distance < 2000) {
            Start.getInstance().MapKit().setScale(25000);
        } else if (distance < 4000) {
            Start.getInstance().MapKit().setScale(10000);
        } else if (distance < 8000) {
            Start.getInstance().MapKit().setScale(5000);
        } else if (distance < 16000) {
            Start.getInstance().MapKit().setScale(2500);
        } else if (distance < 32000) {
            Start.getInstance().MapKit().setScale(1000);
        } else if (distance < 64000) {
            Start.getInstance().MapKit().setScale(500);
        } else if (distance < 128000) {
            Start.getInstance().MapKit().setScale(250);
        } else if (distance < 256000) {
            Start.getInstance().MapKit().setScale(125);
        } else {
            Start.getInstance().MapKit().setScale(50);
        }
    }

    public double getWayTrailDistance(long starttime, long endtime) {
        double distance = 0;//米
        TrackPointDao trackPointDao = AppContext.getInstances().getDaoSession().getTrackPointDao();

        //速度求和
        try {
            Database db = trackPointDao.getDatabase();
            // ---执行SQL---
            String strSQL = "SELECT SUM(SPEED) FROM TRACK_POINT WHERE DATETIME > " + starttime + " AND DATETIME <= " + endtime;
            if (starttime >= endtime) {
                strSQL = "SELECT SUM(SPEED) FROM TRACK_POINT WHERE DATETIME > " + starttime;
            }

            Cursor cursor = db.rawQuery(strSQL, null);
            while (cursor.moveToNext()) {
                distance = cursor.getDouble(0);
                break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return distance;
    }

    public int getWayTrailMoveTime(long starttime, long endtime) {
        int time = 0;//秒
        TrackPointDao trackPointDao = AppContext.getInstances().getDaoSession().getTrackPointDao();

        //航迹运动的时间
        try {
            Database db = trackPointDao.getDatabase();
            // ---执行SQL---
            String strSQL = "SELECT COUNT(*) FROM TRACK_POINT WHERE DATETIME > " + starttime + " AND DATETIME <= " + endtime;
            if (starttime >= endtime) {
                strSQL = "SELECT COUNT(*) FROM TRACK_POINT WHERE DATETIME > " + starttime;
            }

            strSQL += " AND SPEED >= 1 ";
            Cursor cursor = db.rawQuery(strSQL, null);
            while (cursor.moveToNext()) {
                time = cursor.getInt(0);
                break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return time;
    }

    public double getWayTrailAveragevel(long starttime, long endtime) {
        double averagevel = 0;//秒
        TrackPointDao trackPointDao = AppContext.getInstances().getDaoSession().getTrackPointDao();

        //航迹运动点的平均速度
        try {
            Database db = trackPointDao.getDatabase();
            // ---执行SQL---
            String strSQL = "SELECT AVG(SPEED) FROM TRACK_POINT WHERE DATETIME > " + starttime + " AND DATETIME <= " + endtime;
            if (starttime >= endtime) {
                strSQL = "SELECT AVG(SPEED) FROM TRACK_POINT WHERE DATETIME > " + starttime;
            }

            strSQL += " AND SPEED >= 1 ";
            Cursor cursor = db.rawQuery(strSQL, null);
            while (cursor.moveToNext()) {
                averagevel = cursor.getDouble(0);
                break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return averagevel;
    }

    int alarmNum = 0;//最多1分钟播报一次

    public void alarmWarning(Context context) {
        if (warningList == null) {
            return;
        }

        String strW = "";
        LonLat carLL = SysUtils.getInstance().getLL();
        for (WayPoint wp : warningList) {
            LonLat ll = wp.getLL();
            if (Math.abs(ll.GetLon() - carLL.GetLon()) > 0.01
                    || Math.abs(ll.GetLat() - carLL.GetLat()) > 0.01) {
                continue;
            }
            double distance = Start.getInstance().MapKit().getDistance(ll, carLL);
            if (distance > wp.getRange()) {
                continue;
            }

            if (alarmNum > 60) {
                alarmNum = 0;
            }

            if (alarmNum == 0) {
                strW += wp.getName() + " ";
            } else if (alarmNum % 6 == 0) {
                if (context != null) {
                    MediaPlayer mediaPlayer01;
                    mediaPlayer01 = MediaPlayer.create(context, R.raw.notify);
                    mediaPlayer01.start();
                }
            }
//            break;
        }
        alarmNum++;

        if (strW.length() > 1) {
            String strInfo = "您已进入警告点 " + strW + "的警告区域！";
            TtsSpeaker.getInstance().talk(strInfo);
            Toast.makeText(context, strInfo, Toast.LENGTH_LONG).show();
        }
    }


}
